home *** CD-ROM | disk | FTP | other *** search
Text File | 1997-05-21 | 11.0 KB | 354 lines | [TEXT/CWIE] |
- program DropMounter;
-
- (*
- File: DropMounter.p
-
- Contains: A tiny utility to mount disk images using the AsyncDriverSample.
-
- Written by: Quinn "The Eskimo!"
-
- Copyright: © 1996 by Apple Computer, Inc., all rights reserved.
-
- Change History (most recent first):
-
- You may incorporate this sample code into your applications without
- restriction, though the sample code has been provided "AS IS" and the
- responsibility for its operation is 100% yours. However, what you are
- not permitted to do is to redistribute the source as "DSC Sample Code"
- after having made changes. If you're going to re-distribute the source,
- we require that you make it clear in the source that the code was
- descended from Apple Sample Code, but that you've made changes.
- *)
-
- (* This application is a trivial DropShell type program that first installs
- the disk image mounting driver (in this case it's ".AsyncDriverSample"
- although the name of the driver is in a resource, so the application
- can be retargetted).
- After that it spins in a main event loop, handling AppleEvents as they
- come in. In response to a Open Document AppleEvent, the program calls
- the driver to process the file. The ".AsyncDriverSample" sample responds
- to this by mounting the disk image.
- *)
-
- uses
- Types,
- Files,
- EPPC,
- AppleEvents,
- Memory,
- Errors,
- Events,
- QuickDraw,
- Fonts,
- Windows,
- Menus,
- TextEdit,
- Dialogs,
- TextUtils,
- Devices,
- Resources,
-
- TradDriverLoaderLib,
-
- AsyncDriverCommon;
-
- (* ***** Application Resource Equates ***** *)
-
- const
- (* STR *)
- rDriverNameString = 128; (* The name of the 'DRVR' we are to install. *)
- rPhysicalDescriptionString = 200; (* The physical description string to pass to the driver. *)
- rMediaDescriptionString = 200; (* The media description string to pass to the driver. *)
- (* ICN# *)
- rPhysicalIcon = 200; (* The physical icon to pass to the driver. *)
- rMediaIcon = 201; (* The media icon to pass to the driver. *)
- (* vers *)
- rDriverVersion = 200; (* The version of the device driver. *)
- (* ALRT *)
- rErrorAlert = 128;
- rAboutAlert = 129;
-
-
- (* ***** Global Variables ***** *)
-
- var
- gQuitNow: Boolean; (* Set to true when you want the main event loop to stop. *)
- gDriverRefNum : DriverRefNum; (* The refnum of the disk image mounting driver. *)
-
- (* ***** Silly Little Utilities ***** *)
-
- procedure DisplayError(errNum : OSStatus);
- (* A trivial error dialog. *)
- var
- junk : integer;
- errStr : Str255;
- begin
- if (errNum <> noErr) & (errNum <> userCanceledErr) then begin
- NumToString(errNum, errStr);
- ParamText(errStr, '', '', '');
- junk := StopAlert(rErrorAlert, nil);
- end; (* if *)
- end; (* DisplayError *)
-
- procedure BlockClear(baseAddr: univ Ptr; size: longint);
- (* Why oh why doesn't the OS provide this!?! *)
- begin
- while (size > 0) do begin
- baseAddr^ := 0;
- inc(longint(baseAddr));
- size := size - 1;
- end; (* while *)
- end; (* BlockClear *)
-
- (* ***** Core Functions ***** *)
-
- function DoOpenApplication : OSStatus;
- (* In response to the Open Application AppleEvent, we display the about box. *)
- var
- junk : integer;
- begin
- junk := Alert(rAboutAlert, nil);
- gQuitNow := true;
- DoOpenApplication := noErr;
- end; (* DoOpenApplication *)
-
- function DoOpenDocument(fss : FSSpec) : OSStatus;
- (* In response to the Open Document AppleEvent, call the disk image driver
- to mount the disk image.
-
- Note that use of PBControlImmed. This is critical to the successful operation
- of the driver. The driver must have non-interrupt time to mount the image.
- If you call PBControlSync, the call could be delayed by a
- pending async call. The sync call would then start at
- interrupt time, and the device driver would fail horrible.
-
- See Technote 1067 for an extended description of this issue.
-
- <http://devworld.apple.com/dev/technotes/tn/tn1067.html>
- *)
- var
- err: OSStatus;
- mpb : MountParamBlock;
- begin
- mpb.ioCRefNum := gDriverRefNum;
- mpb.csCode := kMountImageControlCode;
- mpb.csParamFileToMount := @fss;
- err := PBControlImmed(@mpb);
- gQuitNow := true;
- DoOpenDocument := err;
- end; (* DoOpenDocument *)
-
- function InstallAndOpenDriver : OSErr;
- var
- err : OSErr;
- driverName : Str255;
- initParamBlock : SecondaryInitParamBlock;
- mediaIcon : IconType;
- physicalIcon : IconType;
- physicalLocationString : Str255;
- tmpResourceH : Handle;
- begin
- (* Get the name for the driver and install it. *)
- driverName := GetString(rDriverNameString)^^;
- err := TradInstallDriverFromResource(0, @driverName,
- 48,
- TradHighestUnitNumber + 1,
- gDriverRefNum);
- if (err = noErr) or (err = dupFNErr) then begin
- err := TradOpenInstalledDriver(gDriverRefNum, fsRdWrPerm);
- end; (* if *)
-
- (* Now send it the secondary init control call, passing in all sorts of nice resource info. *)
- if err = noErr then begin
-
- (* First clear out the paramblock, so if any of the resources fail to load
- we have defined results.
- *)
- BlockClear(@initParamBlock, sizeof(initParamBlock));
-
- (* Get and copy in the driver version. *)
- tmpResourceH := Get1Resource('vers', rDriverVersion);
- if tmpResourceH <> nil then begin
- initParamBlock.csParamVersion := VersRecHndl(tmpResourceH)^^.numericVersion;
- end; (* if *)
-
- (* Get and copy in the media icon. *)
- tmpResourceH := Get1Resource('ICN#', rMediaIcon);
- if tmpResourceH <> nil then begin
- BlockMove(tmpResourceH^, @initParamBlock.csParamMediaIcon, sizeof(IconType));
- end; (* if *)
-
- (* Get and copy in the location string. *)
- tmpResourceH := Get1Resource('STR ', rMediaDescriptionString);
- if tmpResourceH <> nil then begin
- initParamBlock.csParamMediaDescription := StringHandle(tmpResourceH)^^;
- end; (* if *)
-
- (* Get and copy in the physical icon. *)
- tmpResourceH := Get1Resource('ICN#', rPhysicalIcon);
- if tmpResourceH <> nil then begin
- BlockMove(tmpResourceH^, @initParamBlock.csParamPhysicalIcon, sizeof(IconType));
- end; (* if *)
-
- (* Get and copy in the location string. *)
- tmpResourceH := Get1Resource('STR ', rPhysicalDescriptionString);
- if tmpResourceH <> nil then begin
- initParamBlock.csParamPhysicalDescription := StringHandle(tmpResourceH)^^;
- end; (* if *)
-
- (* Now fill in the rest of the initParamBlock and send it to the driver. *)
- initParamBlock.ioCRefNum := gDriverRefNum;
- initParamBlock.csCode := kSecondaryInitControlCode;
- err := PBControlImmed(@initParamBlock);
- end; (* if *)
-
- InstallAndOpenDriver := err;
- end; (* InstallAndOpenDriver *)
-
- (* ***** Standard AppleEvent Handling Stuff ***** *)
-
- function AEGotRequiredParams (theAppleEvent: AppleEvent): OSStatus;
- (* Copied out of "Inside Macintosh: Inter-Application Communications". *)
- var
- typeCode: DescType;
- actualSize: Size;
- err: OSStatus;
- begin
- err := AEGetAttributePtr(theAppleEvent, keyMissedKeywordAttr, typeWildCard, typeCode, nil, 0, actualSize);
- if err = errAEDescNotFound then begin
- err := noErr;
- end else if err = noErr then begin
- err := errAEEventNotHandled;
- end; (* if *)
- AEGotRequiredParams := err;
- end; (* AEGotRequiredParams *)
-
- function HandleAEOpenApplication (var theAppleEvent : AppleEvent; var reply: AppleEvent; refcon : longint): OSErr;
- (* Handle the Open Application AppleEvent. Basically this does the standard AppleEvent
- stuff, then passes the event off to the DoOpenApplication routine.
- *)
- var
- err: OSStatus;
- begin
- {$unused reply}
- {$unused refcon}
- err := AEGotRequiredParams(theAppleEvent);
- if err = noErr then begin
- err := DoOpenApplication;
- if err <> noErr then begin
- if AEInteractWithUser(kAEDefaultTimeout, nil, nil) = noErr then begin
- DisplayError(err);
- end; (* if *)
- end; (* if *)
- end; (* if *)
- HandleAEOpenApplication := err;
- end; (* HandleAEOpenApplication *)
-
- function HandleAEOpenDocuments (var theAppleEvent : AppleEvent; var reply: AppleEvent; refcon : longint): OSErr;
- (* Handle the Open Documents AppleEvent. Basically this does the standard AppleEvent
- stuff, then passes the event off to the DoOpenDocument routine.
- *)
- var
- err : OSStatus;
- docList: AEDescList;
- numberOfItemsInList: longint;
- index : longint;
- docToOpen: FSSpec;
- junkKeyword: AEKeyword;
- junkActualSize: Size;
- junkTypeCode: DescType;
- junkErr : OSStatus;
- begin
- {$unused reply}
- {$unused refcon}
- err := AEGetParamDesc(theAppleEvent, keyDirectObject, typeAEList, docList);
- if err = noErr then begin
- err := AEGotRequiredParams(theAppleEvent);
- if err = noErr then begin
- err := AECountItems(docList, numberOfItemsInList);
- end; (* if *)
- if err = noErr then begin
- for index := 1 to numberOfItemsInList do begin
- if AEGetNthPtr(docList, index, typeFSS, junkKeyword, junkTypeCode, @docToOpen, sizeof(docToOpen), junkActualSize) = noErr then begin
- err := DoOpenDocument(docToOpen);
- if err <> noErr then begin
- if AEInteractWithUser(kAEDefaultTimeout, nil, nil) = noErr then begin
- DisplayError(err);
- end; (* if *)
- end; (* if *)
- end; (* if *)
- end; (* for *)
- err := noErr;
- end; (* if *)
- junkErr := AEDisposeDesc(docList);
- end; (* if *)
- HandleAEOpenDocuments := err;
- end; (* HandleAEOpenDocuments *)
-
- function HandleAEQuitApplication (var theAppleEvent, reply: AppleEvent; refcon : longint): OSErr;
- (* Handle the Quit AppleEvent. Basically this does the standard AppleEvent stuff, then
- sets gQuitNow and the application falls out of the main event loop.
- *)
- var
- err: OSStatus;
- begin
- {$unused reply}
- {$unused refcon}
- err := AEGotRequiredParams(theAppleEvent);
- if err = noErr then begin
- gQuitNow := true;
- end; (* if *)
- HandleAEQuitApplication := err;
- end; (* HandleAEQuitApplication *)
-
- (* ***** The Main Line! ***** *)
-
- var
- err: OSErr;
- junk: OSErr;
- junkBool: boolean;
- event: EventRecord;
- begin
- (* Standard toolbox initialisation, courtesy of ObiWan. *)
- InitGraf(@qd.thePort);
- InitFonts;
- InitWindows;
- InitMenus;
- TEInit;
- InitDialogs(nil);
- MaxApplZone;
- MoreMasters;
-
- (* Install our AppleEvent handlers. Better hope we have System 7 (-: *)
- junk := AEInstallEventHandler(kCoreEventClass, kAEOpenApplication,
- NewAEEventHandlerProc(@HandleAEOpenApplication), 0, false);
- junk := AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments,
- NewAEEventHandlerProc(@HandleAEOpenDocuments), 0, false);
- junk := AEInstallEventHandler(kCoreEventClass, kAEQuitApplication,
- NewAEEventHandlerProc(@HandleAEQuitApplication), 0, false);
-
- (* Now install the driver. *)
- err := InstallAndOpenDriver;
-
- (* If everything is cool, do the main event loop. *)
- if err = noErr then begin
- gQuitNow := false;
- while not gQuitNow do begin
- junkBool := WaitNextEvent(everyEvent, event, maxlongint, nil);
- case event.what of
- keyDown:
- gQuitNow := true;
- kHighLevelEvent:
- junk := AEProcessAppleEvent(event);
- otherwise
- ;
- end; (* case *)
- end; (* while *)
- end; (* if *)
-
- (* Display any errors starting up. *)
- if err <> noErr then begin
- DisplayError(err);
- end; (* if *)
- end. (* MungeInstaller *)
-